﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Manager.Log
{
    /// <summary>
    /// Log analyzer form
    /// </summary>
    public partial class LogAnalyzerForm : Form
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="LogAnalyzerForm"/> class.
        /// </summary>
        public LogAnalyzerForm()
        {
            InitializeComponent();
        }

        string m_logPath;

        /// <summary>
        /// Gets or sets the log path.
        /// </summary>
        /// <value>The log path.</value>
        public string LogPath
        {
            get { return m_logPath; }
            set 
            {
                m_logPath = value;

                LoadLogFile();
            }
        }

        /// <summary>
        /// Loads the log file.
        /// </summary>
        private void LoadLogFile()
        {
            logDataGridView.SuspendLayout();

            LogParser parser = new LogParser();
            parser.LogPath = m_logPath;
            parser.Parse();
            List<LogEntry> logLines = parser.LogEntries;
            logDataGridView.DataSource = logLines;
            logLinesCountToolStripStatusLabel.Text = string.Format("Lines: {0}", logLines.Count);

            logDataGridView.ResumeLayout();
        }

        /// <summary>
        /// Handles the Click event of the closeToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        /// <summary>
        /// Handles the CheckedChanged event of the dateCheckBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void dateCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (dateCheckBox.Checked)
            {
                dateFromDateTimePicker.Enabled = true;
                dateToDateTimePicker.Enabled = true;
            }
            else
            {
                dateFromDateTimePicker.Enabled = false;
                dateToDateTimePicker.Enabled = false;
            }

            FilterRows();
        }

        /// <summary>
        /// Removes the row filters.
        /// </summary>
        private void RemoveFilters()
        {
            CurrencyManager cm = (CurrencyManager)BindingContext[logDataGridView.DataSource];
            cm.SuspendBinding();

            foreach (DataGridViewRow row in logDataGridView.Rows)
            {
                row.Visible = true;
            }

            cm.ResumeBinding();
        }


        /// <summary>
        /// Filters the rows by user filter conditions.
        /// </summary>
        protected virtual void FilterRows()
        {
            logDataGridView.SuspendLayout();
            CurrencyManager cm = (CurrencyManager)BindingContext[logDataGridView.DataSource];
            cm.SuspendBinding();

            RemoveFilters();

            foreach (DataGridViewRow row in logDataGridView.Rows)
            {
                if (dateCheckBox.Checked)
                {
                    FilterRowByDate(row);
                }
                if (timeCheckBox.Checked && row.Visible)
                {
                    FilterRowByTime(row);
                }
                if (informationCheckBox.Checked && row.Visible)
                {
                    FilterRowByInformation(row);
                }
            }

            CountRowsAfterFiltering();

            cm.ResumeBinding();
            logDataGridView.ResumeLayout();
        }

        /// <summary>
        /// Counts the rows after filtering.
        /// Displays the result in the status strip.
        /// </summary>
        /// <returns></returns>
        private int CountRowsAfterFiltering()
        {
            int logLinesCount = 0;

            // Count number of lines
            foreach (DataGridViewRow row in logDataGridView.Rows)
            {
                if (row.Visible)
                {
                    logLinesCount++;
                }
            }

            
            // Set filtered lines number label
            if (dateCheckBox.Checked ||
                timeCheckBox.Checked ||
                informationCheckBox.Checked)
            {
                filteredLinesCountToolStripStatusLabel.Text = string.Format("Lines after filtering: {0}", logLinesCount);
                filteredLinesCountToolStripStatusLabel.Visible = true;
            }
            else
            {
                filteredLinesCountToolStripStatusLabel.Visible = false;
            }

            return logLinesCount;
        }

        /// <summary>
        /// Filters the row by information field.
        /// </summary>
        /// <param name="row">The row.</param>
        private void FilterRowByInformation(DataGridViewRow row)
        {
            string informationString = row.Cells["informationColumn"].Value.ToString();

            if (informationCheckBox.Checked &&
                !informationString.ToLower().Contains(informationContainsTextBox.Text.ToLower()))
            {
                row.Visible = false;
            }
        }

        /// <summary>
        /// Filters the row by time field.
        /// </summary>
        /// <param name="row">The row.</param>
        private void FilterRowByTime(DataGridViewRow row)
        {
            string rowTimeString = row.Cells["timeColumn"].Value.ToString();
            DateTime rowTime;
            DateTime.TryParse(rowTimeString, out rowTime);

            string fromTimeString = timeFromMaskedTextBox.Text;
            DateTime fromTime;
            DateTime.TryParse(fromTimeString, out fromTime);
            
            string toTimeString = timeToMaskedTextBox.Text;
            DateTime toTime;
            DateTime.TryParse(toTimeString, out toTime);

            if(rowTime!= DateTime.MinValue &&
                fromTime != DateTime.MinValue &&
                toTime != DateTime.MinValue &&
                (rowTime.TimeOfDay < fromTime.TimeOfDay ||
                rowTime.TimeOfDay > toTime.TimeOfDay))
            {
                row.Visible = false;
            }
        }

        /// <summary>
        /// Filters the row by date field.
        /// </summary>
        /// <param name="row">The row.</param>
        /// <returns></returns>
        protected virtual bool FilterRowByDate(DataGridViewRow row)
        {
            string dateString = row.Cells["dateColumn"].Value.ToString();
            DateTime date;
            DateTime.TryParse(dateString, out date);

            if (date != DateTime.MinValue &&
                (date < dateFromDateTimePicker.Value.Date ||
                date > dateToDateTimePicker.Value.Date))
            {
                row.Visible = false;
                return false;
            }

            return true;
        }



        /// <summary>
        /// Handles the ValueChanged event of the dateFromDateTimePicker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void dateFromDateTimePicker_ValueChanged(object sender, EventArgs e)
        {
            FilterRows();
        }

        /// <summary>
        /// Handles the ValueChanged event of the dateToDateTimePicker control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void dateToDateTimePicker_ValueChanged(object sender, EventArgs e)
        {
            FilterRows();
        }

        /// <summary>
        /// Handles the CheckedChanged event of the timeCheckBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void timeCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (timeCheckBox.Checked)
            {
                timeFromMaskedTextBox.Enabled = true;
                timeToMaskedTextBox.Enabled = true;
            }
            else
            {
                timeFromMaskedTextBox.Enabled = false;
                timeToMaskedTextBox.Enabled = false;
            }

            FilterRows();
        }

        /// <summary>
        /// Handles the Load event of the LogAnalyzerForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void LogAnalyzerForm_Load(object sender, EventArgs e)
        {
            timeFromMaskedTextBox.Text = "00:00:00";
            timeToMaskedTextBox.Text = "23:59.59";
        }

        /// <summary>
        /// Handles the TextChanged event of the timeFromMaskedTextBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void timeFromMaskedTextBox_TextChanged(object sender, EventArgs e)
        {
            if (timeFromMaskedTextBox.Enabled)
            {
                string fromTimeString = timeFromMaskedTextBox.Text;
                DateTime fromTime;
                if (DateTime.TryParse(fromTimeString, out fromTime))
                {
                    FilterRows();
                }
            }

        }

        /// <summary>
        /// Handles the TextChanged event of the timeToMaskedTextBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void timeToMaskedTextBox_TextChanged(object sender, EventArgs e)
        {
            if (timeToMaskedTextBox.Enabled)
            {
                string toTimeString = timeToMaskedTextBox.Text;
                DateTime toTime;
                if (DateTime.TryParse(toTimeString, out toTime))
                {
                    FilterRows();
                }
            }
        }

        /// <summary>
        /// Handles the CheckedChanged event of the informationCheckBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void informationCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (informationCheckBox.Checked)
            {
                informationContainsTextBox.Enabled = true;
            }
            else
            {
                informationContainsTextBox.Enabled = false;
            }
            
            FilterRows();
        }

        /// <summary>
        /// Handles the TextChanged event of the informationContainsTextBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void informationContainsTextBox_TextChanged(object sender, EventArgs e)
        {
            FilterRows();
        }

        /// <summary>
        /// Handles the Click event of the panelToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void panelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            panelToolStripMenuItem.Checked = !panelToolStripMenuItem.Checked;
            filterPanel.Visible = panelToolStripMenuItem.Checked;
        }

        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadLogFile();
        }
    }
}
